package cz.muni.fi.xvano1.trinity.data;

import cz.muni.fi.xvano1.trinity.supplementary.CalendarHandler;
import cz.muni.fi.xvano1.trinity.core.Core;
import cz.muni.fi.xvano1.trinity.core.SecondaryParser;
import java.io.IOException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import net.fortuna.ical4j.model.component.VEvent;

/**
 * Class for interpreting request for licenses. It is implemented as a Map of
 * String to Integer.
 *
 * @author Jan Vano
 */
public class LicenseRequest {

    private Map<String, Integer> licenses;

    public LicenseRequest() {
        licenses = new HashMap<String, Integer>();
    }

    /**
     * Method returns the request.
     * @return Map of request.
     */
    public Map<String, Integer> getLicenses() {
        return licenses;
    }

    /**
     * Method for setting the request.
     * @param licenses Map of new request.
     */
    public void setLicenses(Map<String, Integer> licenses) {
        this.licenses = licenses;
    }

    /**
     * Method for accessing specific toolbox license in a request.
     * @param name Name of toolbox license in a request
     * @return Number of requested toolbox licenses
     */
    public int getLicense(String name) {
        return licenses.get(name);
    }

    /**
     * Method for setting specific toolbox license in a request.
     * @param name Name of toolbox license in a request
     * @param count Count of toolbox license in a request
     */
    public void setLicense(String name, Integer count) {
        licenses.put(name, count);
    }

    /**
     * Method for removing specific toolbox license from a request.
     * @param name ame of toolbox license in a request
     */
    public void removeLicense(String name) {
        licenses.remove(name);
    }

    /*
     * Removing non positive counts.
     */
    private void normalize() {
        Map<String, Integer> temp = new HashMap<String, Integer>(licenses);
        Set<String> keys = licenses.keySet();
        for (String key : keys) {
            if (licenses.get(key) <= 0) {
                temp.remove(key);
            }
        }
        licenses = temp;
    }

    /**
     * This method generates String representation of request. This representation
     * will be used as a iCalendar parameter for reservation.
     * @return String representation of a request
     */
    public String generateString() {
        normalize();
        String result = "";
        Set<String> keys = licenses.keySet();
        Set<String> allowedKeys = SecondaryParser.getToolboxNames(Core.toolboxDirectory);
        String temp = "";
        int size = keys.size();
        int i = 1;
        for (String key : keys) {
            if (allowedKeys.contains(key)) {
                if (i != size) {
                    temp = licenses.get(key) + " " + key + "\\,";
                } else {
                    temp = licenses.get(key) + " " + key;
                }
                result = result + temp;
            }
            i++;
        }
        return result;
    }

    /**
     * This method reads its parameter as an interpretation of a request for
     * reservation. Specific manner of working with this String is described
     * in bachelor thesis of Lukas Jane (https://is.muni.cz/th/325264/fi_b/)
     * @param description iCalendar field description which should contain request
     * @return Map interpretation of String to Integer of the supplied parameter
     */
    public static Map<String, Integer> parseString(String description) {
        Map<String, Integer> result = new HashMap<String, Integer>();
        Set<String> allowedKeys = SecondaryParser.getToolboxNames(Core.toolboxDirectory);
        String[] split = description.split(","); //povodne \\\\,
        for (String string : split) {
            if (string.startsWith(" ")){
                string = string.substring(1);
            }
            String[] temp = string.split(" ");
            if (temp.length == 1) {
                try {
                    int count = Integer.parseInt(temp[0]);
                    if (count <= 0) {
                        continue;
                    }
                    if (result.containsKey("MATLAB")) {
                        int matlab = result.get("MATLAB");
                        matlab = matlab + count;
                        result.put("MATLAB", matlab);
                    } else {
                        result.put("MATLAB", count);
                    }
                    continue;
                } catch (NumberFormatException ex) {
                    String key = temp[0];
                    if (allowedKeys.contains(key)) {
                        if (result.containsKey(key)) {
                            int toolbox = result.get(key);
                            toolbox++;
                            result.put(key, toolbox);
                        } else {
                            result.put(key, 1);
                        }
                    }
                    continue;
                }
            } else if (temp.length == 2) {
                String key = temp[1];
                try {
                    int count = Integer.parseInt(temp[0]);
                    if (count <= 0) {
                        continue;
                    }
                    if (allowedKeys.contains(key)) {
                        if (result.containsKey(key)) {
                            int toolbox = result.get(key);
                            toolbox = toolbox + count;
                            result.put(key, toolbox);
                        } else {
                            result.put(key, count);
                        }
                        continue;
                    }
                } catch (NumberFormatException ex) {
                    continue;
                }
            } else {
                continue;
            }
        }
        return result;
    }
}
